<!--
 * @Descripttion: 
 * @Author: Kevin
 * @Date: 2022-06-13 17:02:25
 * @LastEditors: Tommy Chen
 * @LastEditTime: 2024-08-28
-->
<template>
  <div>
    <div class="total-panel">
      <div
        :class="['card', currentView == 'total' ? 'current' : '']"
        @click="onTabView('total')"
      >
        <div class="total-content">
          <div>
            <div class="card-title">All</div>
            <div class="total">{{ totalClientNum }}</div>
          </div>
        </div>
      </div>
      <div
        :class="['card', currentView == 'online' ? 'current' : '']"
        @click="onTabView('online')"
      >
        <div class="total-content">
          <div>
            <div class="card-title">{{ $t('newIndex.deviceCount') }}</div>
            <div class="total">
              {{ onlineClientNum }}
            </div>
          </div>
        </div>
      </div>
      <div
        :class="['card', currentView == 'offline' ? 'current' : '']"
        @click="onTabView('offline')"
      >
        <div class="total-content">
          <div>
            <div class="card-title">{{ $t('newIndex.alarmCount') }}</div>
            <div class="total">{{ totalClientNum - onlineClientNum }}</div>
          </div>
        </div>
      </div>
    </div>
    <LayoutPanel class="private-common-wrapper" style="height: auto">
      <div slot="title" class="title">
        <span>{{ $t('portalUser.authUser') }}</span>
        <span class="online status title-txt">
          {{ $t('portalUser.onlineNum', [onlineClientNum]) }}
        </span>
      </div>
      <rj-table
        :columns="portalClientColumns"
        :dataSource="portalClients"
        :pagination="pagination"
        :loading="isTableLoading"
        rowKey="uuid"
        filtercolumns
        @refeshTable="getPortalClientList"
        :scroll="{ x: 2000 }"
        @change="handleTableChange"
      >
        <div slot="customBlock" class="log-opt-wrapper">
          <a-space :size="16">
            <a-select
              v-model="deviceGroupId"
              @change="refreshView"
              style="width: 200px"
            >
              <icon-font type="ic-tree-device" slot="menuItemSelectedIcon" />
              <a-select-option
                v-for="item in authDeviceGroups"
                :key="item.id"
                :title="item.name"
              >
                {{ item.name }}
              </a-select-option>
            </a-select>
          </a-space>

          <a-space :size="16">
            <a-input-search
              class="w-200"
              :placeholder="$t('userManage.accountPlaceholder')"
              v-model="queryParamObj.account"
              @change="onChangeSearch"
            />
            <a-button @click="onShowMore" class="icon-btn">
              {{ $t('common.advancedFilter') }}
              <icon-font :type="isMoreVisible ? 'ic-up' : 'ic-down'" />
            </a-button>
          </a-space>
        </div>

        <template slot="onlineStatus" slot-scope="text">
          <rj-space v-if="text == 0">
            <span class="offline status">{{ $t('common.offline') }}</span>
          </rj-space>
          <rj-space v-if="text == 1">
            <span class="online status">{{ $t('common.online') }}</span>
          </rj-space>
        </template>

        <template slot="timeColumn" slot-scope="text">
          {{ formatDate(text) }}
        </template>

        <template slot="deviceInfo" slot-scope="text">
          {{ !text ? '--' : text }}
        </template>

        <template slot="deviceGroup" slot-scope="text">
          {{ getAuthDeviceGroupName(text) }}
        </template>

        <template slot="authMethod" slot-scope="text">
          {{ getAuthTypeTxt(text) }}
        </template>

        <div
          class="table-adv-content"
          slot="advSearchEleBlock"
          v-show="isMoreVisible"
        >
          <div class="adv-search-item">
            <label>{{ $t('portalUser.userIp') }}</label>
            <a-input
              v-model="queryParamObj.userIp"
              class="adv-search-ipt"
              :placeholder="$t('common.inuptTip')"
            >
            </a-input>
          </div>
          <div class="adv-search-item">
            <label>{{ $t('portalAuth.userMac') }}</label>
            <a-input
              class="adv-search-ipt"
              v-model="queryParamObj.userMac"
              :placeholder="$t('common.inuptTip')"
            />
          </div>
          <div class="adv-search-item btn-item">
            <a-button type="primary" @click="refreshView">
              {{ $t('common.search') }}
            </a-button>
            <a-button @click="onReset">
              {{ $t('common.reset') }}
            </a-button>
          </div>
        </div>

        <!-- 操作 -->
        <template slot="action" slot-scope="text, record">
          <a-spin v-show="record.loading">
            <a-icon
              slot="indicator"
              type="loading"
              style="font-size: 16px"
              spin
            />
          </a-spin>
          <a-popconfirm
            :ok-text="$t('common.confirm')"
            :cancel-text="$t('common.cancel')"
            @confirm="onKickout(text, record)"
            v-show="record.onlineStatus == 1 && record.sourceType == 1"
          >
            <template #title>
              <span style="display: block">{{
                $t('portalUser.isOffline1')
              }}</span>
              <span style="display: block">{{
                $t('portalUser.isOffline2')
              }}</span>
            </template>
            <icon-font
              type="ic-tool-kickoff"
              :title="$t('portalUser.kickOff')"
            ></icon-font>
          </a-popconfirm>
        </template>
      </rj-table>
    </LayoutPanel>
  </div>
</template>

<script>
import { maccApi } from '@utils/index';
import LayoutPanel from '@views/common/deviceDetail/components/components/layoutPanel.vue';
import { RjTable } from '@components';
import authSysMixin from '@project/authSys/mixin/authSysMixin';
import { authTypes } from './authTypes';
import { portalClientColumns } from './columns.js';
import lodash from 'lodash';
import moment from 'moment-timezone';
export default {
  name: 'authClient',
  mixins: [authSysMixin],
  components: {
    'rj-table': RjTable,
    LayoutPanel,
  },
  data() {
    return {
      authTypes,
      portalClientColumns,
      isMoreVisible: false,
      pagination: {
        pageSizeOptions: ['10', '20', '50'],
        total: 0,
        current: 1,
        pageSize: 10,
      },
      portalClients: [],
      isTableLoading: false,
      authDeviceGroups: [
        {
          id: 0,
          name: this.$t('common.all'),
        },
      ],
      queryParamObj: {
        account: '',
        userIp: '',
        userMac: '',
        onlineStatus: '',
      },
      deviceGroupId: 0,
      totalClientNum: 0,
      onlineClientNum: 0,
      currentView: 'total',
    };
  },
  async mounted() {
    await this.getAuthDeviceGroupList();
    this.refreshView({ isInit: true });
  },
  computed: {
    authTypeMap() {
      const tempMap = {};
      this.authTypes.forEach((item) => {
        tempMap[item.value] = item.text;
      });
      return tempMap;
    },
    authDeviceGroupMap() {
      const tempMap = {};
      for (const group of this.authDeviceGroups) {
        tempMap[group.id] = group.name;
      }
      return tempMap;
    },
  },
  methods: {
    onTabView(view) {
      if (view === 'total') {
        this.queryParamObj.onlineStatus = '';
      } else if (view === 'online') {
        this.queryParamObj.onlineStatus = '1';
      } else if (view === 'offline') {
        this.queryParamObj.onlineStatus = '0';
      }
      this.currentView = view;
      this.refreshView();
    },
    formatDate(updateTime) {
      return updateTime ? moment(updateTime).format('YYYY-MM-DD HH:mm:ss') : '';
    },
    onReset() {
      this.queryParamObj.userIp = '';
      this.queryParamObj.userMac = '';
    },
    async onShowMore() {
      this.isMoreVisible = !this.isMoreVisible;
    },
    onChangeSearch() {
      this.getListDebounce();
    },
    getListDebounce: lodash.debounce(function () {
      this.refreshView();
    }, 500),
    getAuthDeviceGroupName(value) {
      const groupName = this.authDeviceGroupMap[value];
      return groupName ? groupName : '';
    },
    refreshView(param) {
      this.getPortalClientList(param);
      this.getPortalClientCount(param);
    },
    getAuthTypeTxt(value) {
      return this.authTypeMap[value]; // 显示具体的portal方式，sms，一键认证这些
    },
    // 确定下线
    async onKickout(text, record) {
      let params = {
        group_id: this.groupId,
        account: record.account,
        auth_type: record.authType,
        mac: record.userMac,
        id: record.id,
      };
      record.loading = true;
      const ret = await this.requestHttpAuth({
        api: maccApi.MACC_USER_OFFLINE_POST_API,
        method: 'POST',
        params,
      });
      record.loading = false;
      if (ret.data.code == 0) {
        this.refreshView();
        if (ret?.data?.data === false) {
          this.$message.warning(this.$t('portalUser.offlineTip'));
        } else {
          this.$message.success(this.$t('common.optSuccess'));
        }
      } else {
        this.$message.warning(ret.data.msg);
      }
    },

    async getAuthDeviceGroupList() {
      const res = await this.requestHttpAuth({
        api: maccApi.PRIVATE_DEVICE_GROUP_GET_API,
        method: 'GET',
        querys: {
          groupId: this.groupId,
          page: 1,
          size: 100,
        },
      });

      if (res.data.success) {
        this.authDeviceGroups = [
          ...this.authDeviceGroups,
          ...res.data.result.items,
        ];
      } else {
        this.$message.warning(res.data.message);
      }
    },

    handleTableChange(pagination, filterObj) {
      this.pagination = pagination;
      this.queryParamObj.onlineStatus = filterObj.onlineStatus || '';
      this.refreshView();
    },
    async getPortalClientCount() {
      const querys = {
        tenantId: this.tenantInfo.tenantId,
      };
      if (this.deviceGroupId) {
        querys.loginArea = this.deviceGroupId;
      }

      this.isTableLoading = true;
      const res = await this.requestHttpAuth({
        api: maccApi.MACC_USER_COUNT_GET_API,
        method: 'GET',
        replaces: {
          tenantName: this.tenantInfo.tenantName,
          groupId: this.groupId,
        },
        querys,
      });
      this.isTableLoading = false;
      if (res.data.success) {
        this.onlineClientNum = res.data.result.onlineUserCount;
      } else {
        this.$message.warning(res.data.message);
      }
    },

    async getPortalClientList(param = { isInit: false }) {
      const querys = {
        tenantId: this.tenantInfo.tenantId,
        page: this.pagination.current,
        size: this.pagination.pageSize,
        account: this.queryParamObj.account,
        userIp: this.queryParamObj.userIp,
        userMac: this.queryParamObj.userMac,
      };
      if (this.queryParamObj.onlineStatus) {
        querys.onlineStatus = this.queryParamObj.onlineStatus;
      }

      if (this.deviceGroupId) {
        querys.loginArea = this.deviceGroupId;
      }

      this.isTableLoading = true;
      const res = await this.requestHttpAuth({
        api: maccApi.MACC_USER_GET_API,
        method: 'GET',
        replaces: {
          tenantName: this.tenantInfo.tenantName,
          groupId: this.groupId,
        },
        querys,
      });
      this.isTableLoading = false;
      if (res.data.success) {
        this.pagination.total = res.data.result.total;
        this.portalClients = res.data.result.items;

        if (param.isInit) {
          this.totalClientNum = res.data.result.total;
        }
      } else {
        this.$message.warning(res.data.message);
        this.totalClientNum = 0;
      }
    },
  },
};
</script>

<style lang="less" scoped>
.total-panel {
  display: flex;
  padding-bottom: 16px;
  background: #f0f3f6;
  .card {
    background-color: @white;
    padding: 16px;
    width: 280px;
    height: 112px;
    .border-radius;
    margin-right: 16px;
    border: 2px solid transparent;
    cursor: pointer;
    &:last-child {
      margin-right: 0;
    }
    &.current {
      border-color: @theme-color;
      box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.08);
      position: relative;
      &::after {
        content: '';
        position: absolute;
        width: 0;
        height: 0;
        border-left: 6px solid transparent;
        border-right: 6px solid transparent;
        border-top: 6px solid @theme-color;
        bottom: -8px;
        left: 50%;
        margin-left: -3px;
      }
    }
    .total-content {
      display: flex;
      justify-content: space-between;
      align-items: center;
      .card-title {
        font-weight: 400;
        font-size: 12px;
        line-height: 20px;
        color: @text-primary;
      }
      .total {
        font-weight: 600;
        font-size: 24px;
        line-height: 32px;
        color: @text-title;
      }
    }
    .message {
      margin-top: 8px;
      text-align: left;
      height: 16px;
      overflow: hidden;
      font-weight: 400;
      font-size: 12px;
      line-height: 16px;
      & > div.anim {
        // 设定滚动
        transition: all 0.5s;
        margin-top: -30px; //高度等于行高
      }
      & > div {
        display: inline-block;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        width: 100%;
        &::before {
          content: '';
          width: 6px;
          height: 6px;
          border-radius: 3px;
          margin-right: 5px;
          display: inline-block;
        }
      }
      &.success {
        color: @success-color;
        & > div {
          &::before {
            background-color: @success-color;
          }
        }
      }
      &.error {
        color: @error-color;
        & > div {
          &::before {
            background-color: @error-color;
          }
        }
      }
    }
  }
}
.table-adv-content {
  padding: 12px;
  background: @bg-component;
  border-radius: 4px;
  margin-bottom: 12px;
  text-align: left;
  display: flex;
  gap: 16px 40px;
  flex-wrap: wrap;
  .adv-search-item {
    display: inline-block;
    & > label {
      width: 180px;
      display: inline-block;
      padding-right: 16px;
      text-align: right;
    }
    & > span {
      width: 320px !important;
    }
    & > input {
      width: 320px;
    }
    &.btn-item {
      display: flex;
      gap: 16px;
      margin-left: auto;
    }
  }
}
.private-common-wrapper {
  padding: 16px;
  height: 100%;
  overflow-y: auto;
  .title {
    display: flex;
    justify-content: space-between;
  }
}
.log-opt-wrapper {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  box-sizing: border-box;
}
.down-arrow {
  color: @success-color;
}
.up-arrow {
  color: @theme-color;
}
.status {
  display: flex;
  align-items: center;
  gap: 4px;
  font-weight: 400;
  &::before {
    content: '';
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 3px;
  }
  &.online {
    &::before {
      background: @success-color;
    }
  }
  &.offline {
    &::before {
      background: @component-border;
    }
  }
}
.anticon {
  font-size: 16px;
}
.w-200 {
  width: 200px;
}
</style>
